﻿#region

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using Radovici.Ctrls.Facebook;
using Radovici.SharedLibrary;
using YouTubePlaylist.Models;

#endregion

namespace YouTubePlaylist.MusicVideoService
{
    public partial class LogMessage
    {
        #region Private fields

        private object _dropableContext;

        #endregion

        //#region FacebookIntegration
        //public FacebookApi.FacebookUser FacebookUser
        //{
        //    get { return DataLayer.Singleton.FacebookApi.GetUser(User.ExternalKey); }
        //}

        //public bool CanPublish
        //{
        //    get
        //    {
        //        return FacebookUser == DataLayer.Singleton.FacebookApi.User &&
        //               Command.StartsWith("Add") &&
        //               !IsPublished;
        //    }
        //}
        //#endregion

        public object DropableContext
        {
            get
            {
                switch (Command)
                {
                    case "AddPlaylist":
                        return DataLayer.Singleton.GetPlaylist(Parameters[0], Callback);
                    case "AddTrack":
                        return DataLayer.Singleton.GetTrack(Parameters[1], Callback);
                    case "CopyPlaylist":
                        return DataLayer.Singleton.GetPlaylist(Parameters[0], Callback);
                    case "DeletePlaylist":
                        return DataLayer.Singleton.GetPlaylist(Parameters[0], Callback);
                    case "DeleteTrackFromPlaylist":
                        return DataLayer.Singleton.GetTrack(Parameters[1], Callback);
                    case "RefreshTrack":
                        return DataLayer.Singleton.GetTrack(Parameters[0], Callback);
                    case "SaveTrackUrl":
                        return DataLayer.Singleton.GetTrack(Parameters[0], Callback);
                    default:
                        return null;
                }
            }
        }

        public string Display
        {
            get
            {
                try
                {
                    switch (Command)
                    {
                        case "AddPlaylist":
                            {
                                VideoPlaylist vp = DataLayer.Singleton.GetPlaylist(Parameters[0], Callback);
                                return string.Format("added playlist '{0}'",
                                                     vp == null ? Parameters[0].ToString() : vp.Name);
                            }
                        case "AddTrack":
                            {
                                VideoPlaylist vp = DataLayer.Singleton.GetPlaylist(Parameters[0], Callback);
                                VideoTrack vt = DataLayer.Singleton.GetTrack(Parameters[1], Callback);
                                return string.Format("added track '{1}' to playlist '{0}'",
                                                     vp == null ? Parameters[0].ToString() : vp.Name,
                                                     vt == null ? Parameters[1].ToString() : vt.Name);
                            }
                        case "CopyPlaylist":
                            {
                                VideoPlaylist vp = DataLayer.Singleton.GetPlaylist(Parameters[0], Callback);
                                return string.Format("copied playlist '{0}'",
                                                     vp == null ? Parameters[0].ToString() : vp.Name);
                            }
                        case "DeletePlaylist":
                            {
                                VideoPlaylist vp = DataLayer.Singleton.GetPlaylist(Parameters[0], Callback);
                                return string.Format("deleted playlist '{0}'",
                                                     vp == null ? Parameters[0].ToString() : vp.Name);
                            }
                        case "DeleteTrackFromPlaylist":
                            {
                                VideoPlaylist vp = DataLayer.Singleton.GetPlaylist(Parameters[0], Callback);
                                VideoTrack vt = DataLayer.Singleton.GetTrack(Parameters[1], Callback);
                                return string.Format("deleted track '{1}' from playlist '{0}'",
                                                     vp == null ? Parameters[0].ToString() : vp.Name,
                                                     vt == null ? Parameters[1].ToString() : vt.Name);
                            }
                        case "RefreshTrack":
                            {
                                VideoTrack vt = DataLayer.Singleton.GetTrack(Parameters[0], Callback);
                                return string.Format("refreshed track {0}'s videos",
                                                     vt == null ? Parameters[0].ToString() : vt.Name);
                            }
                        case "SaveTrackUrl":
                            {
                                VideoTrack vt = DataLayer.Singleton.GetTrack(Parameters[0], Callback);
                                return string.Format("saved track {0}'s video selection",
                                                     vt == null ? Parameters[0].ToString() : vt.Name);
                            }
                    }
                }
                catch (Exception ex)
                {
                    return string.Format("{0} {1} (*)", Command, Parameters.Count);
                }
                return string.Format("{0} {1}", Command, Parameters);
            }
        }

        private void Callback()
        {
            Notify("DropableContext");
            Notify("Display");
        }

        private bool _isPublished;
        public bool IsPublished
        {
            get { return _isPublished; }
            set 
            { 
                _isPublished = value;
                Notify("IsPublished");
                Notify("CanPublish");
            }
        }

        private void Notify(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        public override int GetHashCode()
        {
            return Id;
        }

        public override bool Equals(object obj)
        {
            var msg = obj as LogMessage;
            if (msg != null)
            {
                return msg.Id == Id;
            }
            return false;
        }
    }

    public partial class Track
    {
        public override string ToString()
        {
            return Name;
        }
    }

    public partial class User
    {
        public User()
        {
            Preferences = DataLayer.DefaultPreferences;
        }
    }

    public partial class VideoPlaylist
    {
        public void Add(Track track)
        {
            var vt = new VideoTrack();
            vt.Artist = track.Artist;
            vt.Name = track.Name;
            DataLayer.Singleton.AddTrack(this, vt);
        }

        public void Add(VideoTrack track)
        {
            DataLayer.Singleton.AddTrack(this, track);
        }

        public VideoPlaylist GetEmptyCopy()
        {
            var tmp = new VideoPlaylist();
            tmp.Id = Id;
            tmp.Name = Name;
            tmp.Description = Description;
            tmp.Tracks = new ObservableCollection<VideoTrack>();
            return tmp;
        }

        public override int GetHashCode()
        {
            return Id;
        }

        public override bool Equals(object obj)
        {
            var playlist = obj as VideoPlaylist;
            if (playlist != null)
            {
                if (Name.Equals(playlist.Name, StringComparison.InvariantCultureIgnoreCase))
                {
                    return ListFunctionality.Equals(Tracks, playlist.Tracks);
                }
            }
            return false;
        }

        public void UpdateTrack(VideoTrack track)
        {
            VideoTrack t = Tracks.SingleOrDefault(tmp => tmp.Id == track.Id);
            if (t != null)
            {
                t.Copy(track);
            }
            else
            {
                Tracks.Add(track);
            }
            DataLayer.MaintainTrack(track);
        }

        public void Copy(VideoPlaylist playlist)
        {
            Name = playlist.Name;
            Notify("Name");
            foreach (VideoTrack track in playlist.Tracks)
            {
                UpdateTrack(track);
            }
            Notify("Tracks");
        }

        private void Notify(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }

    public partial class VideoTrack
    {
        public VideoTrackUrl SelectedUrl
        {
            get { return Url ?? ((Urls != null && Urls.Count > 0) ? Urls[0] : null); }
        }

        public override int GetHashCode()
        {
            return Id;
        }

        public override bool Equals(object obj)
        {
            var track = obj as VideoTrack;
            if (track != null)
            {
                return Artist == track.Artist
                       && Name == track.Name
                       &&
                       (Url != null && track.Url != null && Equals(Url, track.Url) || (Url == null && track.Url == null))
                       && ListFunctionality.Equals(Urls, track.Urls);
            }
            return false;
        }

        public void Copy(VideoTrack track)
        {
            Artist = track.Artist;
            Category = track.Category;
            Name = track.Name;
            Url = track.Url;
            Urls = track.Urls;
            NotifyAll();
        }

        private void NotifyAll()
        {
            Notify("Artist");
            Notify("Category");
            Notify("Title");
            Notify("Url");
            Notify("Urls");
            Notify("SelectedUrl");
        }

        private void Notify(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }

    public partial class VideoTrackUrl
    {
        public string Thumbnail
        {
            get
            {
                if (Optional != null && Optional.ContainsKey("Thumbnail"))
                {
                    return Optional["Thumbnail"];
                }
                return string.Empty;
            }
        }

        public string Link
        {
            get
            {
                if (Optional != null && Optional.ContainsKey("Link"))
                {
                    return Optional["Link"];
                }
                return string.Empty;
            }
        }

        // override object.Equals
        public override bool Equals(object obj)
        {
            var tmp = obj as VideoTrackUrl;
            if (tmp != null)
            {
                return (Title == tmp.Title && Url == tmp.Url);
            }
            return false;
        }

        // override object.GetHashCode
        public override int GetHashCode()
        {
            return Url.GetHashCode();
        }

        public override string ToString()
        {
            return Title;
        }
    }
}